package com.eqxiu.ieditor.order.service.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.eqxiu.ieditor.order.OrderStatusEnum;
import com.eqxiu.ieditor.order.dao.OrderDao;
import com.eqxiu.ieditor.order.dao.OrderItemDao;
import com.eqxiu.ieditor.order.dto.ItemDTO;
import com.eqxiu.ieditor.order.dto.OrderDTO;
import com.eqxiu.ieditor.order.model.Order;
import com.eqxiu.ieditor.order.model.OrderExample;
import com.eqxiu.ieditor.order.model.OrderItem;
import com.eqxiu.ieditor.order.service.MD5Util;
import com.eqxiu.ieditor.order.service.OrderService;

@Component
public class OrderServiceImpl implements OrderService {

    @Value("${payment.appkey}")
    private String appKey;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderItemDao orderItemDao;

    @Override
    public String signParam(Map<String, Object> param) {
        SortedMap<String, Object> smap = new TreeMap<String, Object>(param);
        StringBuffer stringBuffer = new StringBuffer();
        for (Map.Entry<String, Object> m : smap.entrySet()) {
            Object value = m.getValue();
            if (value != null && !"".equals(String.valueOf(value))) {
                try {
                    stringBuffer.append(m.getKey()).append("=")
                        .append(URLEncoder.encode(String.valueOf(value), "UTF-8")).append("&");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        stringBuffer.delete(stringBuffer.length() - 1, stringBuffer.length());
        String argPreSign = stringBuffer.append("&payKey=").append(appKey).toString();
        String signStr = MD5Util.encode(argPreSign).toUpperCase();
        System.out.println("this is sigin=>>>>" + signStr);
        return signStr;
    }

    @Override
    @Transactional(readOnly = false)
    public void createOrder(OrderDTO orderDTO) {
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO, order);
        order.setStatus(OrderStatusEnum.NEW.status());
        order.setCreateTime(new Date());
        orderDao.insert(order);
        orderDTO.setId(order.getId());

        List<ItemDTO> items = orderDTO.getItems();
        if (items != null) {
            for (ItemDTO dto : items) {
                OrderItem item = new OrderItem();
                BeanUtils.copyProperties(dto, item);
                item.setCode(order.getProductCode());
                item.setOrderId(order.getId());
                item.setCreateTime(new Date());
                orderItemDao.insertSelective(item);
            }
        }
    }

    @Override
    public Optional<OrderDTO> selectByPrimaryKey(Long id) {
        Order order = orderDao.selectByPrimaryKey(id);

        if (Objects.nonNull(order)) {
            OrderDTO dto = new OrderDTO();
            BeanUtils.copyProperties(order, dto);
            return Optional.of(dto);
        }
        return Optional.empty();
    }

    @Override
    public Optional<List<OrderDTO>> selectByExample(OrderExample example) {
        List<Order> orders = orderDao.selectByExample(example);
        if (Objects.nonNull(orders) && orders.size() > 0) {
            return Optional.of(orders.stream().map(one -> {
                OrderDTO dto = new OrderDTO();
                BeanUtils.copyProperties(one, dto);
                return dto;
            }).collect(Collectors.toList()));
        }

        return Optional.empty();
    }

    @Override
    public Optional<OrderDTO> findOrder(String orderSn) {
        OrderExample example = new OrderExample();
        example.createCriteria().andOutOrderIdEqualTo(orderSn);

        List<Order> orders = orderDao.selectByExample(example);

        if (orders != null && orders.size() > 0) {
            OrderDTO dto = new OrderDTO();
            BeanUtils.copyProperties(orders.get(0), dto);
            return Optional.of(dto);
        }
        return Optional.empty();
    }

    @Override
    @Transactional(readOnly = false)
    public int finishOrder(OrderDTO dto) {
        Order order = new Order();
        BeanUtils.copyProperties(dto, order);
        return orderDao.updateByPrimaryKeySelective(order);
    }

}
